package com.algorithm.liyc.echa;

import com.algorithm.liyc.entity.TreeNode;

import java.util.ArrayList;
import java.util.List;

/**
 * 二叉树的前中后序遍历（递归法）
 *
 * 递归算法的三个要素。每次写递归，都按照这三要素来写，可以保证大家写出正确的递归算法！
 * 1.  确定递归函数的参数和返回值：
 * 确定哪些参数是递归的过程中需要处理的，那么就在递归函数里加上这个参数， 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
 * 2.  确定终止条件：
 * 写完了递归算法,  运行的时候，经常会遇到栈溢出的错误，就是没写终止条件或者终止条件写的不对，操作系统也是用一个栈的结构来保存每一层递归的信息，如果递归没有终止，操作系统的内存栈必然就会溢出。
 * 3.  确定单层递归的逻辑：
 * 确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。
 * @author Liyc
 * @date 2023/12/26 16:08
 **/

public class Solution1 {
    /**
     * 前序遍历·递归·LC144_二叉树的前序遍历
     * @param root
     * @return
     */
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        inorder(root, result);
        return result;
    }
    public void inorder(TreeNode root, List<Integer> result) {
        if (root == null) {
            return;
        }
        result.add(root.val);
        inorder(root.left, result);
        inorder(root.right, result);
    }

    /**
     * 中序遍历·递归·LC94_二叉树的中序遍历
     * @param root
     * @return
     */
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        preorder(root, result);
        return result;
    }
    public void preorder(TreeNode root, List<Integer> result) {
        if (root == null) {
            return;
        }
        preorder(root.left, result);
        result.add(root.val);
        preorder(root.right, result);
    }

    /**
     * 后序遍历·递归·LC145_二叉树的后序遍历
     * @param root
     * @return
     */
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        postorder(root, result);
        return result;
    }
    public void postorder(TreeNode root, List<Integer> result) {
        if (root == null) {
            return;
        }
        postorder(root.left, result);
        postorder(root.right, result);
        result.add(root.val);
    }

}
